unit UTableForm;

interface

uses
  Windows, Messages, Types, SysUtils, Variants, Classes, Graphics, Controls,
  Forms, Dialogs, ExtCtrls, StdCtrls, Generics.Collections,
  DB, DBGrids, IBCustomDataSet,
  UDatabase, UTable, UField, UFilterFrame, ULog,
  URecEditForm, UFilterMgrFrame, Grids, JvDBGridExport,
  Excel_TLB, Menus, Buttons, JvComponentBase;

type
  TTableForm = class(TForm)
    DSource: TDataSource;
    DSet: TIBDataSet;
    DGrid: TDBGrid;
    btAppend: TButton;
    pnTop: TPanel;
    btDelete: TButton;
    splFilter: TSplitter;
    FilterMgr: TFilterMgrFrame;
    ExcelExport: TJvDBGridExcelExport;
    pmExport: TPopupMenu;
    mnExcel: TMenuItem;
    mnHTML: TMenuItem;
    mnODF: TMenuItem;
    SaveDialog: TSaveDialog;
    jvHTMLExport: TJvDBGridHTMLExport;
    btExport: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure DGridTitleClick(Column: TColumn);
    procedure DGridDblClick(Sender: TObject);
    procedure btAppendClick(Sender: TObject);
    procedure btDeleteClick(Sender: TObject);
    procedure DSetAfterTransactionEnd(Sender: TObject);
    procedure mnExportClick(Sender: TObject);
  private
    FTable: TTable;
    FDescSort: boolean;
    FCards: TCardsAdd;
    FSQL: PSQLRec;
  public
    procedure UpdateQuery;
    procedure PrepareQuery;
    procedure ExecuteQuery;
    destructor Destroy; override;
    constructor Create(AOwner: TComponent; Order: integer); reintroduce;
  end;

var
  TableForms: array of TTableForm;

procedure CreateTableForm(Order: integer; Owner: TComponent);

implementation

const
  SaveFormats: array[TSaveFormat] of integer = (1, $2C, $3C);

{$R *.dfm}

procedure CreateTableForm(Order: integer; Owner: TComponent);
begin
  if TableForms[Order] <> nil then begin
    Restore(TableForms[Order]);
  end else
    TableForms[Order] := TTableForm.Create(Owner, Order);
end;

constructor TTableForm.Create(AOwner: TComponent; order: integer);
begin
  inherited Create(AOwner);
  FTable := Tables[order];
  FCards := TCardsAdd.Create(DSet, FTable, False);
end;

procedure TTableForm.btDeleteClick(Sender: TObject);
begin
  PromptDeleteCurrent(DSet);
  ExecuteQuery;
  Activate;
end;

destructor TTableForm.Destroy;
begin
  TableForms[FTable.Order] := nil;
  FCards.OwnsObjects := True;
  FreeAndNil(FCards);
  inherited;
end;

procedure TTableForm.DGridDblClick(Sender: TObject);
begin
  FCards.AttemptToAddCurrent;
end;

procedure TTableForm.DGridTitleClick(Column: TColumn);
const
  a: array[boolean] of string = ('ASC', 'DESC');
function GetStr: string;
begin
  Result := Format('%s "%s" %s', [SortBy, Column.FieldName, a[FDescSort]]);
end;
begin
  FDescSort := not FDescSort and (FSQL.SortStr = GetStr);
  FSQL.SortStr := GetStr;
  UpdateQuery;
end;

procedure TTableForm.DSetAfterTransactionEnd(Sender: TObject);
begin
  UpdateQuery;
end;

procedure TTableForm.ExecuteQuery;
begin
  Log.TryExecuteQuery(DSet, FSQL);
end;

procedure TTableForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FTable.Position.Rect := BoundsRect;
  FTable.Columns.Assign(DGrid.Columns);
  Action := caFree;
end;

procedure TTableForm.FormCreate(Sender: TObject);
begin
  Caption := FTable.Caption;
  BoundsRect := FTable.Position.Rect;
  FilterMgr.Init(FTable, UpdateQuery);
  FSQL := @FTable.SQL;
  FTable.Columns.AssignTo(DGrid.Columns);
  if taInsert in FTable.Actions then begin
    DSet.GeneratorField.Field := FTable.PrimaryKey.Name;
    DSet.GeneratorField.Generator := Format(GenFmt, [UpperCase(FTable.Name)]);
  end else
    btAppend.Hide;
  DSet.SelectSQL.Append(FSQL.Select);
  DSet.InsertSQL.Append(FSQL.InsertStr);
  DSet.DeleteSQL.Append(FSQL.DeleteStr);
  DSet.ModifySQL.Append(FSQL.ModifyStr);
  ExecuteQuery;
end;

procedure TTableForm.mnExportClick(Sender: TObject);
const
  Exts: array[TSaveFormat] of string = ('xls', 'html', 'ods');
var
  Fmt: TSaveFormat;
  jvExport: TJvCustomDBGridExport;
begin
  Fmt := TSaveFormat((Sender as TComponent).Tag);
  SaveDialog.DefaultExt := Exts[Fmt];
  SaveDialog.FilterIndex := Succ(Ord(Fmt));
  if not SaveDialog.Execute then
    Exit;
  Fmt := TSaveFormat(Pred(SaveDialog.FilterIndex));
  if Fmt <> sfHtml then begin
    ExcelExport.SaveFormat := Fmt;
    jvExport := ExcelExport;
  end else
    jvExport := jvHTMLExport;
  jvExport.FileName := SaveDialog.FileName;
  jvExport.ExportGrid;
end;

procedure TTableForm.btAppendClick(Sender: TObject);
begin
  FCards.Append;
end;

procedure TTableForm.UpdateQuery;
begin
  PrepareQuery;
  ExecuteQuery;
end;

procedure TTableForm.PrepareQuery;
begin
  FSQL.WhereStr := FilterMgr.WhereStr;
  DSet.SelectSQL.Text := FSQL.Select;
  FilterMgr.AssignParams(DSet);
end;

initialization
  SetLength(TableForms, TableNumber);

end.
